<?php

namespace App\Http\Controllers\V1\BusinessData;

use App\Http\Requests\V1\CollectDataRequest;
use App\Models\V1\BasicCircuits;
use App\Models\V1\BasicCollectors;
use App\Models\V1\BasicCollectTransformers;
use App\Models\V1\BasicTransformers;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use League\Flysystem\Exception;
use Log;
use DB;

class CircuitController extends Controller
{

    /**
     * 仪表盘的管理页面
     *
     * @return \Illuminate\Http\Response
     */
    public function showInstrumentBoard()
    {
        // 获取最新的采集数据异常的回路，显示该回路的最新的且异常的采集数据
        $currentPage = 1;// 当前页
        $rows = 4; //轮播table每页显示的条数
        $keywords = null;
        $data = $this->getAlarmCircuitList($currentPage,$rows,$keywords);
        $lastPage = $data->lastPage();
        // 根据总的分页数初始化轮播需要的页数
        // 轮播的table展示根据遍历pageArray显示
        $pageArray = array();
        for ($i = 0; $i < $lastPage; $i++){
            // 初始化table的id
            $id = 'dataCarouselTabel'.($i+1);
            array_push($pageArray,$id);
        }
        $dataItem['pageArray'] = $pageArray;
        return view('v1.instrument_board',$dataItem);


    }

    /**
     * 显示回路详细管理页面
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        // 回路编码
        $circuit_code = $request->input('code');
        $isOnlyAlarm = $request->input('isOnlyAlarm');
        $type = '1';// type 1：根据回路编码获取最新的一条采集数据，2：根据采集代码获取采集数据
        $data['code'] = $circuit_code;
        $collectData = $this->getCollectDataByCode($circuit_code,$type);
        $circuitObj = $this->getCircuitByCode($circuit_code);
        $collectorObj  = $this->getCollectorByCode($circuitObj['collector_code']);
        $transformerObj = $this->getTransformerByCode($collectorObj['transformer_code']);

        $data['isOnlyAlarm'] = $isOnlyAlarm;// true：回路详情页面只显示最近一条采集数据是报警数据的回路，采集数据列表只显示有报警信息的采集数据
        $data['device_code'] = $transformerObj['model_code'];
        $data['device_address'] = $transformerObj['address'];
//        $collectData['process_state'] =  $collectData['process_state'] === 1 ? '已处理' : '未处理';
        $collectData['state'] = $circuitObj['state'] === 1 ? '正常' : '异常';
        $collectData['name'] = $circuitObj['name'];
        $collectData['collector_code'] = $circuitObj['collector_code'];
        $data['itemData'] = $collectData;

        return view('v1.circuit_detail',$data);
    }


    /**
     *
     * 获取数据 回路详情中回路所有的报警数据列表
     *
     * @param Request $request
     */
    public function postCircuitAlarmsIndex(Request $request)
    {
        $circuit_code = $request->input('code');
        $response = [
            'code' => 1,
            'msg' => '',
            'count' => 0,
            'data' => [],
        ];

        // 获取符合查询条件的数据
        $currentPage = $request->get('page');
        $rows = $request->get('limit');
        $keywords = $request->get('keywords');

        // 获取符合查询条件的数据
        $data = $this->getCollectDataList($circuit_code,$currentPage, $rows, $keywords);

        if (!$data->isEmpty()) {

            $formatList = array();

            $count = $data->total() > 0 ? $data->total() : 0;

            if ($count > 0) {
                $type = '1'; // type:1 电压、电流、温度 显示数字 type:2 显示灯泡图片
                // 格式化数据
                foreach ($data->items() as $item) {
                    $circuitObj = $item->circuit;
                    $collectorObj  = $this->getCollectorByCode($circuitObj['collector_code']);
                    $transformerObj = $this->getTransformerByCode($collectorObj['transformer_code']);
                    $formatItem['code'] = $item['code'];
                    $formatItem['name'] = $circuitObj['name'];
                    $formatItem['device_name'] = $transformerObj['model_code'];
                    $formatItem['device_address'] = $transformerObj['address'];
                    $formatItem['collector_code'] = $collectorObj['code'];
                    $formatItem['collector_mac_code'] = $collectorObj['mac_code'];
                    $formatItem['temperature'] = $this->formatCollectData($item['temperature'],$type);
                    $formatItem['voltage'] = $this->formatCollectData($item['voltage'],$type);
                    $formatItem['electric'] = $this->formatCollectData($item['electric'],$type);
                    $formatItem['state'] =  $this->formatCollectState($circuitObj['state']);
//                    $formatItem['process_state'] = $this->formatProcessState($item['process_state']);
                    $formatItem['updated_at'] = $item['updated_at']->format('Y-m-d H:i');
                    $formatItem['created_at'] = $item['created_at']->format('Y-m-d H:i');
                    array_push($formatList, $formatItem);
                }

                $response['code'] = 0;
                $response['msg'] = '加载数据成功';
                $response['count'] = $count;
                $response['data'] = $formatList;
            }
        }

        return $response;
    }

    /**
     * 获取数据 所有的报警数据，同一个回路多个报警展示最新的一条
     *
     * @param Request $request
     */
    public function postCircuitsIndex(Request $request)
    {

        $response = [
            'code' => 1,
            'msg' => '',
            'count' => 0,
            'data' => [],
        ];

        // 获取符合查询条件的数据
        $currentPage = $request->get('page');
        $rows = $request->get('limit');
        $keywords = $request->get('keywords');
        $type = $request->get('type');// type ：carousel 获取轮播图里面的table数据

        // 获取符合查询条件的数据
        $data = $this->getAlarmCircuitList($currentPage, $rows, $keywords);
        if (!$data->isEmpty()) {

            $formatList = array();

            $count = $data->total() > 0 ? $data->total() : 0;

            if ($count > 0) {

                // 格式化数据
                foreach ($data->items() as $item) {
                    $collectorData = $this->getAlarmDataByCode($item['code']);
                    $collectDatas = $item->collectDatas;// 该回路下所有的采集数据
                    $tempCount = count($collectDatas);
                    $collectorObj  = $this->getCollectorByCode($item['collector_code']);
                    $transformerObj = $this->getTransformerByCode($collectorObj['transformer_code']);
                    $formatItem['code'] = $item['code']; // 回路编码
//                    $formatItem['name'] = $tempCount > 1 ? $item['name'].'（'.$tempCount.'）' : $item['name'];
                    $formatItem['device_name'] = $transformerObj['model_code'];//变压器客户编码
                    $formatItem['device_address'] = $transformerObj['address'];
                    $formatItem['collector_code'] = $collectorObj['code'];// 采集器编码
                    $formatItem['collector_mac_code'] = $collectorObj['mac_code']; // 采集器mac地址
                    $formatItem['state'] =  $this->formatCollectState($item['state']);
                    $formatItem['process_state'] = $this->formatProcessState($collectorData);
                    $formatItem['updated_at'] = $collectorData['updated_at']->format('Y-m-d H:i');
                    $formatItem['created_at'] = $collectorData['created_at']->format('Y-m-d H:i');

                    $formatType = '1'; // formatType:1 电压、电流、温度 显示数字 formatType:2 显示灯泡图片
                    if (!isset($type) || empty($type)) {// type ：carousel 获取轮播图里面的table数据
                        $formatItem['name'] = $tempCount > 1 ? $item['name'].'（'.$tempCount.'）' : $item['name'];
                        $formatType = '1';
                    }else{
                        $formatItem['name'] = $item['name'];
                        $formatType = '2';
                    }
                    $formatItem['temperature'] = $this->formatCollectData($collectorData['temperature'],$formatType);
                    $formatItem['voltage'] = $this->formatCollectData($collectorData['voltage'],$formatType);
                    $formatItem['electric'] = $this->formatCollectData($collectorData['electric'],$formatType);

                    array_push($formatList, $formatItem);
                }

                $response['code'] = 0;
                $response['msg'] = '加载数据成功';
                $response['count'] = $count;
                $response['data'] = $formatList;
            }
        }

        return $response;
    }

    /**
     * 获取数据， 回路最近24小时内的采集数据
     *
     * @param Request $request
     */
    public function postLatest24HoursCollectData(Request $request)
    {
        $response = [
            'rspStatus' => false,
            'rspMsg' => '回路[' . $request->input('code') . '],数据获取失败！',
        ];

        if ($request->method() === 'POST') {
            // 验证请求
            $rules['code'] = 'bail|required|exists:basic_collect_transformers,circuit_code,deleted_at,NULL';
//            $rules['captcha'] = 'bail|required|captcha';
            $messages['code.required'] = '回路代码不能为空';
            $messages['code.exists'] = '回路代码不存在';
//            $messages['captcha.required'] = '验证码不能为空';
//            $messages['captcha.captcha'] = '验证码错误';

            $this->validate($request, $rules, $messages);

            // 获取最近24小时内回路的采集数据
            $datas = $this->get24HoursCollectDataByCode($request->input('code'));

            // 将datas倒序排列
            $datas =  array_reverse($datas);
            // 初始化返回的data格式
            $result = array(
                'categories' => [],
                'voltages' => [],
                'electrics' => [],
                'temperatures' => []
            );
            $categories = array();
            $voltages = array();
            $electrics = array();
            $temperatures = array();
            foreach ($datas as $data){
                // 格式化时间
                $time = Carbon::parse($data['created_at'])->format('m-d H:i');
                array_push($categories,$time);
                array_push($voltages,$data['voltage']);
                array_push($electrics,$data['electric']);
                array_push($temperatures,$data['temperature']);
            }
            $result['categories'] = $categories;
            $result['voltages'] = $voltages;
            $result['electrics'] = $electrics;
            $result['temperatures'] = $temperatures;
            if ($datas) {
                $response['rspStatus'] = true;
                $response['rspMsg'] = '回路[' . $request->input('code') . '],数据获取成功！';
                $response['data'] = $result;
            }
        }

        return $response;
    }

    /**
     * 进入单条数据显示界面 (适用于新增addData、查看viewData、编辑editData功能）
     *
     * @param Request $request
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function showView(Request $request)
    {
        $data['view'] = $request->input('view');
        $data['code'] = $request->input('code');
        $collectData = $this->getCollectDataByCode($data['code'],'1');
        $circuitObj = $this->getCircuitByCode($collectData['circuit_code']);
        $collectorObj  = $this->getCollectorByCode($circuitObj['collector_code']);
        $transformerObj = $this->getTransformerByCode($collectorObj['transformer_code']);
        switch ($request->input('view')){
            case 'editData':
                $collectData['name'] = $circuitObj['name'];
                $data['itemData'] = $collectData;
                return view('v1.form.collect_datas_item', $data);
                break;
            case 'viewData':
                $data['device_code'] = $transformerObj['model_code'];
                $data['device_address'] = $transformerObj['address'];
                $collectData['state'] = $circuitObj['state'] === 1 ? '正常' : '异常';
                $collectData['name'] = $circuitObj['name'];
                $collectData['collector_code'] = $collectorObj['code'];
                $data['itemData'] = $collectData;
                return view('v1.form.collect_datas_item', $data);
                break;

        }
    }

//    /**
//     * 显示数据导入页面
//     *
//     * @param Request $request
//     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
//     */
//    public function importView(Request $request)
//    {
//        // 获取登录用户
//        $loginUser = Auth::user();
//
//        $data['view'] = $request->input('view');
//        $data['code'] = $loginUser->getAttribute('code');
//
//        return view('v1.form.upload_excel', $data);
//    }

    /**
     * 更新基本信息(单元格)
     *
     * @param CollectDataRequest $request
     * @return array
     */
    public function updateCellData(CollectDataRequest $request)
    {
        $response = [
            'rspStatus' => false,
            'rspMsg' => '采集数据代码[' . $request->input('code') . '],更新失败！',
        ];

        if ($request->method() === 'POST') {
            // 验证请求
            $this->validateCollectData($request);

            // 更新采集数据信息
            $successFlag = $this->handleUpdate($request, true);

            if ($successFlag) {
                $response['rspStatus'] = true;
                $response['rspMsg'] = '采集数据代码[' . $request->input('code') . '],更新成功！';
            }
        }

        return $response;
    }

    /**
     * 更新基本信息
     *
     * @param CollectDataRequest $request
     * @return array
     */
    public function updateData(CollectDataRequest $request)
    {
        $response = [
            'rspStatus' => false,
            'rspMsg' => '采集数据代码[' . $request->input('code') . '],更新失败！',
        ];

        if ($request->method() === 'POST') {
            // 验证请求
            $this->validateCollectData($request);

            // 更新采集数据信息
            $successFlag = $this->handleUpdate($request, false);

            if ($successFlag) {
                $response['rspStatus'] = true;
                $response['rspMsg'] = '采集数据代码[' . $request->input('code') . '],更新成功！';
            }
        }

        return $response;
    }


    /**
     * 删除基本信息
     *
     * @param CollectDataRequest $request
     * @return array
     */
    public function deleteData(CollectDataRequest $request)
    {
        $response = [
            'rspStatus' => false,
            'rspMsg' => '采集数据代码[' . $request->input('code') . '],删除失败！',
        ];

        if ($request->method() === 'POST') {
            // 验证请求
            $this->validateCollectData($request);

            // 删除采集数据信息
            $successFlag = $this->handleDelete($request, false);

            if ($successFlag) {
                $response['rspStatus'] = true;
                $response['rspMsg'] = '采集数据代码[' . $request->input('code') . '],删除成功！';
            }
        }

        return $response;
    }

    /**
     * 批量删除采集数据基本信息
     *
     * @param CollectDataRequest $request
     * @return array
     */
    public function deleteBatchData(CollectDataRequest $request)
    {
        $response = [
            'rspStatus' => false,
            'rspMsg' => '采集数据批量删除失败！',
        ];

        if ($request->method() === 'POST') {

            // 删除采集数据信息
            $successFlag = $this->handleDelete($request, true);

            if ($successFlag) {
                $response['rspStatus'] = true;
                $response['rspMsg'] = '采集数据批量删除成功！';
            }
        }

        return $response;
    }

    ///////////////////////////////////////////////////////////////////
    /// 获取数据功能函数
    ///////////////////////////////////////////////////////////////////
    /**
     * 分页查询指定回路的所有报警数据列表数据
     *
     * @param $circuit_code 回路代码
     * @param int $page 当前页数
     * @param $rows 每页显示条数
     * @param $keywords 搜索关键词
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator 分页对象
     */
    private function getCollectDataList($circuit_code,$page = 1, $rows, $keywords)
    {
        if (!isset($keywords) || empty($keywords)) {
            $data = BasicCollectTransformers::where('circuit_code',$circuit_code)
                ->where(function ($query) {
                    $query->where('temperature','>',40)
                        ->orWhere('voltage','>',30)
                        ->orWhere('electric','>',20);
                })
                ->orderBy('created_at', 'desc')
                ->paginate($rows, ['*'], 'page', $page);
        } else {
            $data = BasicCollectTransformers::where('circuit_code',$circuit_code)
                ->where('name', 'like', '%' . $keywords . '%')
                ->where(function ($query) {
                    $query->where('temperature','>',40)
                        ->orWhere('voltage','>',30)
                        ->orWhere('electric','>',20);
                })
                ->orderBy('created_at', 'desc')
                ->paginate($rows, ['*'], 'page', $page);
        }
        return $data;
    }

    /**
     * 查询最新的采集数据异常的回路，显示该回路的最新的且异常的采集数据
     *
     * @param int $page 当前页数
     * @param $rows 每页显示条数
     * @param $keywords 搜索关键词

     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator 分页对象
     */
    private function getAlarmCircuitList($page = 1, $rows, $keywords)
    {
        // 先找出所有有报警数据的回路
        $circuit_codes = BasicCollectTransformers::where('temperature','>',40)
            ->orWhere('voltage','>',30)
            ->orWhere('electric','>',20)
            ->pluck('circuit_code')->unique()->toArray();

        // 判断回路的最新一条数据是否异常，如果正常就删除该回路代码
        $temp_circuit_codes = array(); // 最新一条采集数据异常的回路代码集合
        foreach ($circuit_codes as $circuit_code){
            $collectDataObj = BasicCollectTransformers::where('circuit_code',$circuit_code)
                ->orderBy('created_at', 'desc')->first();
            if ($collectDataObj['temperature'] > 40 || $collectDataObj['voltage'] > 30 || $collectDataObj['electric'] > 20 ){
                array_push($temp_circuit_codes,$collectDataObj['circuit_code']);
            }
        }
        if (!isset($keywords) || empty($keywords)) {
            $data = BasicCircuits::whereIn('code',$temp_circuit_codes)->orderBy('created_at', 'desc')
                ->paginate($rows, ['*'], 'page', $page);
        } else {
            $data = BasicCircuits::where('name', 'like', '%' . $keywords . '%')
                ->whereIn('code',$temp_circuit_codes)
                ->orderBy('created_at', 'desc')
                ->paginate($rows, ['*'], 'page', $page);
        }

        return $data;
    }

    /**
     * 根据回路代码获取最近24小时的采集数据
     * 默认每小时有一条采集数据
     *
     * @param $code
     * @return \Illuminate\Database\Eloquent\Model|null|static
     */
    private function get24HoursCollectDataByCode($code)
    {
        $data = BasicCollectTransformers::where('circuit_code',$code)
            ->orderBy('created_at', 'desc')
            ->get()->toArray();
        if (count($data) > 24){
            $data = array_slice($data,0,24);
        }
        return $data;
    }

    /**
     * 根据回路代码获该回路最新的报警数据
     *
     * @param $code
     * @return \Illuminate\Database\Eloquent\Model|null|static
     */
    private function getAlarmDataByCode($code)
    {
        $data = BasicCollectTransformers::where('circuit_code',$code)
            ->where(function ($query) {
                    $query->where('temperature','>',40)
                        ->orWhere('voltage','>',30)
                        ->orWhere('electric','>',20);
                })
            ->orderBy('created_at', 'desc')
            ->first();
        return $data;
    }

    /**
     * 根据采集数据代码获取对应采集数据信息
     *
     * @param $code
     * @return \Illuminate\Database\Eloquent\Model|null|static
     */
    private function getCollectDataByCode($code,$type)
    {
        // type 1：根据回路编码获取最新的一条采集数据，2：根据采集代码获取采集数据
        if ($type == '1'){
            $data = BasicCollectTransformers::where('circuit_code', $code)
                ->orderBy('created_at', 'desc')
                ->first();
            return $data;
        }else{
            $data = BasicCollectTransformers::where('code', $code)->first();
            return $data;
        }

    }



    /**
     * 根据采集数据代码获取对应变压器信息
     *
     * @param $code
     * @return \Illuminate\Database\Eloquent\Model|null|static
     */
    private function getTransformerByCode($code)
    {
        $transformer = BasicTransformers::where('code', $code)->first();
        return $transformer;
    }

    /**
     * 根据回路代码获取回路信息
     *
     * @param $code
     * @return \Illuminate\Database\Eloquent\Model|null|static
     */
    private function getCircuitByCode($code)
    {
        $data = BasicCircuits::where('code',$code)->first();
        return $data;
    }

    /**
     * 根据采集器代码获取采集器信息
     *
     * @param $code
     * @return \Illuminate\Database\Eloquent\Model|null|static
     */
    private function getCollectorByCode($code)
    {
        $data = BasicCollectors::where('code',$code)->first();
        return $data;
    }




    /**
     * 格式化显示内容类型
     *
     * @param $val
     * @return string
     */
    private function formatProcessState($collectData)
    {
        $process_state = $collectData['process_state'];
        $strFormat = '<span>未知</span>';
        switch ($process_state) {
            case 0:
                $strFormat = '<button class="layui-btn layui-btn-danger layui-btn-small" style="height: 28px;" lay-event="editData">未处理</button>';
                break;
            case 1:
                $strFormat = '<button class="layui-btn layui-btn-small" style="height: 28px;">已处理</button>';
                break;
            case 2:
                $updated_at = $collectData['updated_at']->format('Y-m-d');
                $handler = empty($collectData['handler']) ? '' : '，指派员工:'. $collectData['handler'];
                $title = '指派时间:'.$updated_at.$handler;
                $strFormat = '<button class="layui-btn layui-btn-small" style="height: 28px;" title='.$title.'>处理中</button>';
                break;
        }
        return $strFormat;
    }

    /**
     * 格式化显示内容类型
     *
     * @param $val
     * @return string
     */
    private function formatCollectState($val)
    {
        $strFormat = '<span>未知</span>';
        switch ($val) {
            case 0:
                $strFormat = '<div style=" position: absolute;left: 45%;top: 30%;height:10px;width:10px;border-radius: 5px;background-color: #f53b39;text-align: center; "></div>';
                break;
            case 1:
                $strFormat = '<div style=" position: absolute;left: 45%;top: 30%;height:10px;width:10px;border-radius: 5px;background-color: #23df28;text-align: center; "></div>';
                break;
        }
        return $strFormat;
    }

    /**
     * 格式化显示内容类型
     *
     * @param $val
     * @return string
     */
    private function formatCollectData($val,$type)
    {
        if ($type === '1'){
            if ($val > 30){
                $strFormat = '<p style="color: #f53b39">' .$val.'</p>';
            }else if($val > 20){
                $strFormat = '<p style="color: #fef04b">' .$val.'</p>';
            }
            else{
                $strFormat = '<p style="color: #23df28">' .$val.'</p>';
            }
            return $strFormat;
        }else{
            if ($val > 30){
                $strFormat = '<div style=" position: absolute;left: 45%;top: 30%;height:10px;width:10px;border-radius: 5px;background-color: #f53b39;text-align: center; "></div>';
            }else if($val > 20){
                $strFormat = '<div style=" position: absolute;left: 45%;top: 30%;height:10px;width:10px;border-radius: 5px;background-color: #fef04b;text-align: center; "></div>';
            }
            else{
                $strFormat = '<div style=" position: absolute;left: 45%;top: 30%;height:10px;width:10px;border-radius: 5px;background-color: #23df28;text-align: center; "></div>';
            }
            return $strFormat;
        }

    }


    ///////////////////////////////////////////////////////////////////
    /// 验证表单请求功能函数
    ///////////////////////////////////////////////////////////////////
    /**
     * 处理新增、更新采集数据信息验证请求
     *
     * @param Request $request
     */
    private function validateCollectData(Request $request)
    {
        $rules = $request->rules();
        if ($request->input("captcha") !== null) {
            $rules['captcha'] = 'bail|required|captcha';
        }
        $messages = $request->messages();
        // 执行表单数据验证
        $this->validate($request, $rules, $messages);
    }

    ///////////////////////////////////////////////////////////////////
    /// 业务逻辑功能函数
    ///////////////////////////////////////////////////////////////////
    /**
     * 处理更新采集数据信息
     *
     * @param Request $request
     * @param bool $bCell 是否为单元格修改数据
     * @return bool
     */
    private function handleUpdate(Request $request, $bCell)
    {
        $where = $request->input('code');

        // 拼装更新数据数组
        $updateData = array();
        if ($bCell) { // 单元格修改
            $attrs = $request->input('attrs');
            $values = $request->input('values');
            $counter = 0;
            foreach ($attrs as $attr) {
                $updateData[$attr] = $values[$counter];
                $counter++;
            }
        } else { // 表单修改
            // 拼装更新数据数组

             if ($request->input('process_state') !== "") {
                 $updateData['process_state'] = $request->input('process_state');
             }
        }

        DB::beginTransaction(); // 开启事务
        $successFlag = false;
        try{
            // 更新采集数据信息
            $rspObj = BasicCollectTransformers::where('code', $where)
                ->update($updateData);
            $successFlag = $rspObj;

            if (!$successFlag){
                DB::rollBack();
            }else{
                DB::commit();
            }
            return $successFlag;
        }catch (Exception $exception){
            DB::rollback();
            return $successFlag;
        }
    }

    /**
     * 处理更新采集数据信息
     *
     * @param Request $request
     * @param bool $bBatch 是否为批量数据
     * @return bool
     */
    private function handleDelete(Request $request, $bBatch)
    {
        $where = $request->input('code');

        if ($bBatch) { // 批量删除
            $codeList = $request->input('code');

            foreach ($codeList as $code) {
                $rspObj = BasicCollectTransformers::where('code', $code)->delete();
            }
        } else { // 单条删除
            $rspObj = BasicCollectTransformers::where('code', $where)
                ->delete();
        }

        return $rspObj;
    }


}
